home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 7
/
FM Towns Free Software Collection 7.iso
/
ms_dos
/
thmake
/
thmake.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-11-30
|
21KB
|
1,026 lines
/*
“THmake”MAKEユーティリティー
By 五味
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>
#define TRUE -1
#define FALSE 0
#define SUCCESS 0
#define FAILED -1
#define NONE 0
#define FULL (void *)0xffff
#define LBUFSIZE 4096
/* 行バッファの最大容量 */
char *helpmes= " 'THmake' MAKE utility v1.1b\n"
" (c) H.Gomi 1993/08/12\n"
"\n"
" [usage] THmake [-?hH][-d][-e][-m][-i]\n"
"\t\t[-v][-c][-Dname macro][-t][-p]\n"
"\t\t[-f makefilename] [[making target]...]\n";
struct defdflt {
char *src;
char *dst;
struct defdflt *sp; /* 次へのポインタ */
struct def2way *spn; /* 子項目への子ポインタ */
};
struct def4way {
struct def2way *src;
struct def2way *dst;
struct def4way *sp; /* 次へのポインタ */
struct def2way *spn; /* 子項目への子ポインタ */
};
struct def2way {
char *cen; /* 文 */
struct def2way *sp; /* 次へのポインタ */
};
struct defmac {
char *src; /* 変数名 */
char *dst; /* 内容 */
struct defmac *sp; /* 次へのポインタ */
};
struct defmac *defm,*tdefm,*mdefm; /* 変数定義 */
struct defdflt *defw,*tdefw,*mdefw; /* 省略文法条件 */
struct def2way *defs,*tdefs,*mdefs; /* 省略文法命令 */
struct def4way *defd,*tdefd,*mdefd; /* 制作条件 */
struct def2way *defb,*tdefb;
struct def2way *defa,*tdefa;
struct def2way *defc,*tdefc,*mdefc; /* 制作命令 */
struct def4way *cho; /* 重複チェック */
FILE *fp;
char linebuf[LBUFSIZE]; /* 行バッファ */
char tbuf[LBUFSIZE]; /* バッファ予備 */
char *mfname="makefile"; /* メイクファイルの名前 */
char *outline="make.i"; /* コマンドライン書出 */
char *highest=NULL; /* 最上級オブジェクト */
int high=TRUE; /* ターゲット存在するか */
time_t st[2],dt[2],nt[2]; /* 秒数バッファ */
char pc[]={ ' ','\0' }; /* 間隔記号 */
char fc[]={ 0xff,'\0' }; /* 展開用補助記号 */
unsigned int line=1; /* 行番号 */
int doImake; /* メイク処理をするか */
int doIexec=TRUE; /* コマンド実行するか */
int doIdisp=TRUE; /* コマンド表示するか */
int doIdval=FALSE; /* マクロ内容の表示 */
int doIdpro=FALSE; /* プロセス表示するか */
int doIlist=FALSE; /* 依存関係表示するか */
int doIigno=FALSE; /* 返値を無視するか */
int doIcomm=FALSE; /* インタプリタを通すか */
int doIolyt=FALSE; /* タッチのみか */
int lldisp,llcomm,lligno; /* ローカル属性 */
/*
下級関数群
*/
char *elloc(size_t size) /* メモリオーバーアボート付「malloc」 */
{
char *s;
if( (s=(char *)malloc(size))==NULL ) {
printf(" %s %d: out of memory.\n",mfname,line);
exit(2);
} else
return s;
}
char *estrdup(char *p) /* メモリオーバーアボート付「strdup」 */
{
if( (p=strdup(p)) )
return p;
else {
printf(" %s %d: out of memory.\n",mfname,line);
exit(2);
}
}
/*
フィルタ関数群
*/
void rplmac(char str[])
{
unsigned int srcp,dstp,lp,ef;
strcpy(tbuf,str);
for( srcp=dstp=0 ; tbuf[srcp]!='\0' ; ) {
if( tbuf[srcp]=='$' && tbuf[srcp+1]=='(' ) {
for( srcp+=2,lp=srcp ; tbuf[srcp]!=')' ; srcp++ ) {
if( tbuf[srcp]=='\0' ) {
printf(" %s %d: マクロ展開の表記が異常です.",mfname,line);
exit(1);
}
}
tbuf[srcp++]='\0';
for( tdefm=mdefm,ef=FALSE ; tdefm!=NULL ; tdefm=tdefm->sp ) {
if( strcmp(tdefm->src,&tbuf[lp])==0 ) {
strcpy(&str[dstp],tdefm->dst);
dstp+=strlen(tdefm->dst);
ef=TRUE;
break;
}
}
if( ef==FALSE )
printf(" %s %d: warning: macro'%s' undefined.");
} else {
str[dstp++]=tbuf[srcp++];
}
}
str[dstp]='\0';
}
void execpp(char *str,struct def4way *stp)
{
int ll;
struct def2way *tsp;
char *p,*q;
for( strcpy(linebuf,str) ; (p=strchr(linebuf,'$')) ; ) {
*p='\0';
strcpy(tbuf,linebuf);
switch(*(p+1)) {
case':':
pc[0]=*(p+2);
strcat(tbuf,p+3);
break;
case'<':
strcat(tbuf,stp->src->cen);
strcat(tbuf,p+2);
break;
case'@':
strcat(tbuf,stp->dst->cen);
strcat(tbuf,p+2);
break;
case'#':
for( tsp=stp->src,ll=0 ; tsp!=NULL ; tsp=tsp->sp ) {
if( (ll++) )
strcat(tbuf,pc);
strcat(tbuf,tsp->cen);
}
strcat(tbuf,p+2);
break;
case'?':
for( tsp=stp->src,ll=0 ; tsp!=NULL ; tsp=tsp->sp ) {
gftime(tsp->cen,st);
if( st[0]>nt[0] ) {
if( (ll++) )
strcat(tbuf,pc);
strcat(tbuf,tsp->cen);
}
}
strcat(tbuf,p+2);
break;
case'{':
strcat(tbuf,fc);
strcat(tbuf,p+1);
break;
default:
printf(" %s: マクロ表記が異常です.\n",mfname);
exit(1);
}
strcpy(linebuf,tbuf);
}
for( ; (p=strchr(linebuf,0xff))!=NULL ; ) {
*p='\0';
strcpy(tbuf,linebuf);
strcat(tbuf,outline);
if( (q=strchr(p+2,'}'))==NULL ) {
printf(" %s: '${...}'による展開の表記が不完全です.\n",mfname);
exit(1);
}
if( (fp=fopen(outline,"w"))==NULL ) {
printf(" %s: accident: コマンドライン展開用のファイルが作れません.\n",mfname);
exit(2);
}
*q='\0';
fputs(p+2,fp);
fclose(fp);
strcat(tbuf,q+1);
strcpy(linebuf,tbuf);
}
}
char *linepp(char str[]) /* 行の前処理(返値はlinebuf[...]) */
{
unsigned int lp; /* 行ポインタ */
if( str[0]==EOF )
return FALSE; /* EOF調査 */
*strchr(str,'\n')='\0'; /* CR削除 */
rplmac(str); /* マクロ置換 */
for( lp=0 ; str[lp]==' ' || str[lp]=='\t' ; lp++ );
if( str[lp]=='\0' )
return NULL; /* 空行 */
if( lp>0 )
strcpy(str,&str[lp]); /* 行詰め */
for( lp=strlen(str)-1 ; str[lp]==' ' || str[lp]=='\t' ; lp-- );
str[lp+1]='\0'; /* 行末詰め */
return str;
}
char *getline(void) /* エラーと前処理付き一行入力 */
{
char *p;
size_t l;
for( linebuf[0]='\0' ; (p=fgets(tbuf,LBUFSIZE,fp))!=NULL ; ) {
line++;
strcat(linebuf,tbuf);
if( (p=strchr(linebuf,'#')) )
if( linebuf==p || *(p-1)==' ' || *(p-1)=='\t' )
*p='\0';
if( (l=strlen(linebuf))>2 && linebuf[l-2]=='\\' &&
( linebuf[l-3]==' ' || linebuf[l-3]=='\t' ) )
linebuf[l-2]='\0'; /* 行継続文字 */
else
if( (p=linepp(linebuf)) )
return p;
}
if( feof(fp) )
return NULL;
else {
printf(" %s %d: accident: read failed.\n",mfname,line);
exit(3);
}
}
/*
汎用処理関数群
*/
char *getsrc(char *str) /* 省略表記による下のファイルがあるか否か */
{
char *ttbuf;
struct defdflt *ttdefw; /* tdefw 暗黙使用の為のテンポラリ */
if( strchr(str,'.')==NULL )
return(NONE);
for( tdefw=mdefw->sp,ttbuf=NULL ; tdefw!=NULL ; tdefw=tdefw->sp )
if( stricmp(tdefw->dst,strchr(str,'.')+1)==0 ) {
strcpy(tbuf,str);
strcpy(strchr(tbuf,'.')+1,tdefw->src);
if( access(tbuf,0)==0 ) /* 存在するか? */
return(estrdup(tbuf));
else if( ttbuf==NULL ) {
ttbuf=tbuf;
ttdefw=tdefw;
}
}
if( ttbuf ) {
tdefw=ttdefw;
return(estrdup(ttbuf));
}else
return(NONE);
}
void setbase(void) /* 依存関係の複合構造体のベースを作る */
{
tdefd=(struct def4way *)elloc(sizeof(struct def4way));
defd->sp=tdefd;
defd=tdefd;
defd->sp =NULL; /* メイク条件の保存 */
defd->spn=NULL;
defb=(struct def2way *)elloc(sizeof(struct def2way));
defb->sp =NULL;
defb->cen="\0";
defd->src=defb;
defa=(struct def2way *)elloc(sizeof(struct def2way));
defa->sp =NULL;
defa->cen="\0";
defd->dst=defa;
}
/*
データ処理部
*/
int making(char *str) /* 省略規制利用のシングル */
{
char *srcp,*dstp;
if( (srcp=getsrc(dstp=estrdup(str))) ) {
setbase();
defd->spn=tdefw->spn; /* tdefw 暗黙使用 */
defb->cen=srcp;
defb->sp =NULL;
defa->cen=dstp;
defa->sp =NULL;
return SUCCESS;
} else{
free(srcp);
free(dstp);
return FAILED;
}
}
void execope(char str[]) /* めいめいの方法で実行する */
{
unsigned int ll,lp;
char *opt[64];
if( llcomm==TRUE ) {
if( (ll=system(str))==-1 ) {
printf(" %s : accident: loading 'COMMAND.COM' failed.\n",mfname);
exit(2);
}
} else {
strcpy(tbuf,str);
for( lp=0,ll=0 ; TRUE ; ) {
for( ; str[lp]==' ' ; lp++ );
opt[ll++]=&str[lp];
for( ; str[lp]!=' ' ; lp++ )
if( str[lp]=='\0' )
goto optend;
str[lp++]='\0';
}
optend:
opt[ll]=NULL;
if( *opt[0]!='\0' ) {
if( (ll=spawnvp(P_WAIT,opt[0],opt))==-1 ) {
if( (ll=system(tbuf))==-1 ) {
printf(" %s : accident: can't exec '%s'.\n",mfname,opt[0]);
exit(2);
}
}
}else{
printf(" fatal: exec NULL strings.\n");
exit(3);
}
}
if( ll ) {
if( lligno==FALSE ) {
printf(" break.(errorlevel %d)\n",ll);
exit(ll);
} else {
printf(" ignore error.(level %d)",ll);
}
}
}
void makedo(struct def4way *stp) /* 依存関係を処理 */
{
unsigned int ef;
struct tm *ltime;
struct def2way *tsp;
if( doIdpro==TRUE )
printf(" checking.(%s->%s)\n",stp->src->cen,stp->dst->cen);
for( dt[0]=0,tsp=stp->src ; tsp!=NULL ; tsp=tsp->sp ) {
if( *(tsp->cen)!='\0' ) {
if( gftime(tsp->cen,st) ) {
printf(" %s: can't test time-stamp of '%s'.\n",mfname,tsp->cen);
exit(2);
}
if( st[0]>dt[0] )
dt[0]=st[0];
}
} /* 最も新しいソースの時間を見る */
if( dt[0]==0 ) {
printf(" %s: Don't know how to make '%s'.\n",mfname,stp->dst->cen);
exit(1);
}
for( nt[0]=(time_t)clock(),tsp=stp->dst ; tsp!=NULL ; tsp=tsp->sp ) {
if( *(tsp->cen)!='\0' ) {
if( gftime(tsp->cen,st)==SUCCESS ) {
if( st[0]<nt[0] ) {
nt[0]=st[0];
}
} else
nt[0]=0; /* 無いから「最も古い」 */
}
} /* 最も古いターゲットの時間を得る */
if( doIdpro==TRUE ) {
ltime=localtime(&dt[0]);
printf("\tnewest source file time: %02d/%02d/%02d %02d:%02d:%02d\n",
ltime->tm_year,ltime->tm_mon,ltime->tm_mday,
ltime->tm_hour,ltime->tm_min,ltime->tm_sec);
if( nt[0] ) {
ltime=localtime(&nt[0]);
printf("\toldest target file time: %02d/%02d/%02d %02d:%02d:%02d\n",
ltime->tm_year,ltime->tm_mon,ltime->tm_mday,
ltime->tm_hour,ltime->tm_min,ltime->tm_sec);
if( nt[0]<dt[0] )
printf("\t[up dated]\n");
else
printf("\t[no touch]\n");
} else {
printf("\ttargets not found.\n");
printf("\t[creat]\n");
}
} /* ファイルスタンプ比較の表示 */
highest=stp->dst->cen; /* 最上級ターゲット名の書換え */
if( (nt[0]<dt[0] || doIexec==FALSE) && doIolyt==FALSE ) {
/* ソース群が新しければ処理実行 */
high=FALSE;
for( ef=TRUE,tsp=stp->spn ; tsp!=NULL ; tsp=tsp->sp ) {
ef=FALSE;
execpp(tsp->cen,stp);
for( lldisp=doIdisp,llcomm=doIcomm,lligno=doIigno ;;) {
if( linebuf[0]=='@' )
lldisp=FALSE;
else if( linebuf[0]=='+' )
llcomm=TRUE;
else if( linebuf[0]=='-' )
lligno=TRUE;
else break;
strcpy(linebuf,linebuf+1);
}
if( lldisp==TRUE )
printf("%s\n",linebuf);
if( doIexec==TRUE )
execope(linebuf);
} /* 処理行の実行 */
if( ef==TRUE ) {
for( tsp=stp->dst ; tsp!=NULL ; tsp=tsp->sp ) {
if( utime(tsp->cen,NULL) ) {
printf(" %s: fatal: target'%s' not found.\n",tsp->cen);
exit(2);
}
if( doIdisp==TRUE ) {
printf(" touch '%s'.\n",tsp->cen);
}
} /* touch 処理 */
}
}
stp->src=NULL;
stp->dst=NULL;
stp->spn=NULL; /* 項目から削除 */
}
struct def4way *issrc(char str[]) /* 末端か否か */
{
for( tdefd=mdefd->sp ; tdefd!=NULL ; tdefd=tdefd->sp )
for( tdefb=tdefd->dst ; tdefb!=NULL ; tdefb=tdefb->sp )
if( stricmp(str,tdefb->cen)==0 )
return(tdefd);
return(NULL);
}
void chksrc(struct def4way *stp) /* 関係を調べる */
{
auto struct def2way *rdefb;
auto struct def4way *tsp;
for( rdefb=stp->src ; rdefb!=NULL ; rdefb=rdefb->sp ) {
if( rdefb->cen ) {
if( (tsp=issrc(rdefb->cen))!=NULL ) {
if( tsp==cho ) {
printf(" %s: fatal: '%s'の作り方に矛盾がある.\n",
mfname,stp->dst->cen);
exit(2);
} else {
if( cho==NULL )
cho=tsp;
}
chksrc(tsp);
} else {
if( making(rdefb->cen)==SUCCESS ) {
if( doIdpro==TRUE ) {
printf(" ('%s's source)'%s' owes '%s'.\n",
stp->dst->cen,tdefd->dst->cen,tdefd->src->cen);
}
chksrc(tdefd); /* tdefd 暗黙使用 */
}
}
}
}
cho=NULL;
makedo(stp);
return;
}
void make(void) /* ファイルからのメイク処理 */
{
struct def4way *rdefd;
while(TRUE)
for( cho=NULL,rdefd=mdefd->sp ; ; rdefd=rdefd->sp ) {
if( rdefd==NULL )
return;
if( rdefd->dst->cen ) {
chksrc(rdefd);
break;
}
}
}
/*
データ蓄積部
*/
struct def2way *searsrc(struct def4way *stp,int f)
{
struct def2way *tsp,*rdefs;
char *p;
for( rdefs=NULL,tsp=stp->dst ; tsp!=NULL ; tsp=tsp->sp ) {
if( *(tsp->cen)!='\0' ) {
if( (p=getsrc(tsp->cen)) ) {
if( f++ ) {
tdefb=(struct def2way *)elloc(sizeof(struct def2way));
defb->sp=tdefb;
defb=tdefb;
}
defb->cen=p;
defb->sp =NULL;
if( rdefs==NULL )
rdefs=tdefw->spn;
else
rdefs=FULL;
if( doIdpro==TRUE )
printf(" '%s' owes '%s'.\n",tsp->cen,p);
}
}
} /* 省略規制からソース名を入手 */
return rdefs;
}
void premake(char str[]) /* メイク条件と命令の保存 */
{
struct def2way *rdef,*rdefc;
unsigned int lp,ct,ef;
int ll;
if( doImake==TRUE ) { /* ファイルから依存関係を調べる */
setbase();
for( ef=TRUE,lp=0 ; ef==TRUE ; ) {
for( ; str[lp]==' ' || str[lp]=='\t' ; lp++ );
if( str[lp]==':' ) {
lp++;
break;
}
for( ct=lp ; str[lp]!=' ' && str[lp]!='\t' ; lp++ )
if( str[lp]==':' ) {
ef=FALSE;
break;
}
str[lp++]='\0';
tdefa=(struct def2way *)elloc(sizeof(struct def2way));
defa->sp=tdefa;
defa=tdefa;
defa->cen=estrdup(&str[ct]);
defa->sp =NULL;
}
rdef=defd->dst;
defd->dst=(defd->dst)->sp;
free(rdef); /* ダミーの削除 */
rdefc=searsrc(defd,1); /* 省略規制の該当ソース追加 */
for( ef=TRUE ; ef==TRUE ; ) {
for( ; str[lp]==' ' || str[lp]=='\t' ; lp++ );
if( str[lp]=='\0' ) {
lp++;
break;
}
for( ct=lp ; str[lp]!=' ' && str[lp]!='\t' ; lp++ )
if( str[lp]=='\0' ) {
ef=FALSE;
break;
}
str[lp++]='\0';
tdefb=(struct def2way *)elloc(sizeof(struct def2way));
defb->sp=tdefb;
defb=tdefb;
defb->cen=estrdup(&str[ct]);
defb->sp =NULL;
}
rdef=defd->src;
defd->src=(defd->src)->sp;
free(rdef); /* ダミーの削除 */
}
defc=(struct def2way *)elloc(sizeof(struct def2way));
defd->spn=defc;
defc->cen="\0";
defc->sp =NULL; /* ダミー */
for( ef=TRUE ; TRUE ; ef=FALSE ) {
if( (ll=fgetc(fp))!='\t' ) {
ungetc(ll,fp);
break;
} /* TABだったら続ける */
if( getline() && doImake==TRUE ) {
tdefc=(struct def2way *)elloc(sizeof(struct def2way));
defc->sp=tdefc;
defc=tdefc;
defc->cen=estrdup(linebuf);
defc->sp =NULL;
}
} /* 処理行の保存 */
rdef=defd->spn;
defd->spn=(defd->spn)->sp;
free(rdef); /* ダミーの削除 */
if( defd->spn==NULL && rdefc!=FULL )
defd->spn=rdefc; /* 省略時の処理方法 */
}
void defset(char *str) /* 省略時のパターンのセット */
{
int ll;
char *p;
tdefw=(struct defdflt *)elloc(sizeof(struct defdflt));
defw->sp=tdefw;
defw=tdefw;
defw->sp =NULL; /* 省略条件の保存 */
*(p=strchr(str,'.'))='\0';
if( stricmp(str,p+1)==0 ) {
printf(" %s %d: 省略規制の拡張子指定が違法です.\n",mfname,line);
exit(1);
}
defw->src=estrdup(str);
defw->dst=estrdup(p+1);
defs=(struct def2way *)elloc(sizeof(struct def2way));
defw->spn=defs;
defs->cen="\0";
defs->sp =NULL; /* 省略命令への分岐 */
while( (ll=fgetc(fp))=='\t' )
if( getline() ) {
tdefs=(struct def2way *)elloc(sizeof(struct def2way));
defs->sp=tdefs;
defs=tdefs;
defs->cen=estrdup(linebuf);
defs->sp =NULL;
} /* 省略命令の保存 */
ungetc(ll,fp);
tdefs=defw->spn;
defw->spn=defw->spn->sp;
free(tdefs); /* ダミー削除 */
return;
}
void defmac(char *name,char *val) /* マクロ定義 */
{
for( tdefm=mdefm->sp ; tdefm!=NULL ; tdefm=tdefm->sp )
if( strcmp(tdefm->src,name)==0 ) {
printf(" %s %d: warning: マクロ'%s'の再定義は無効です.\n",mfname,line,name);
return;
}
tdefm=(struct defmac *)elloc(sizeof(struct defmac));
defm->sp=tdefm;
defm =tdefm;
defm->sp=NULL; /* 構造の延長 */
defm->src=name;
defm->dst=val;
}
void macset(char str[]) /* マクロ定義行の読み取り */
{
unsigned int lp,ct,np;
for( lp=0 ; str[lp]==' ' || str[lp]=='\t' ; lp++ );
for( ct=lp ; str[lp]!=' ' && str[lp]!='\t' && str[lp]!='=' ; lp++ );
for( np=lp ; str[lp]!='=' ; lp++ );
str[np]='\0';
for( lp++ ; str[lp]==' ' || str[lp]=='\t' ; lp++ );
defmac(estrdup(&str[ct]),estrdup(&str[lp]));
}
void commands(char str[])
{
int lp,ct;
for( lp=1 ;
str[lp]!=' ' && str[lp]!='\t' && str[lp]!=':' && str[lp]!='\0'
; lp++ );
for( ct=lp ;
str[lp]!=':' && str[lp]!='\0'
; lp++ );
if( str[lp]=='\0' ) {
printf(" %s %d: control error(without':').\n",mfname,line);
exit(1);
}
str[ct]='\0';
if( strchr(str,'.') )
defset(str); /* 省略条件と命令の保存 */
else if( !stricmp(str,"IGNORE") )
doIigno=TRUE;
else if( !stricmp(str,"SILENT") )
doIdisp=FALSE;
else
printf(" %s %d: warning: illegal control('%s').\n",mfname,line,str);
}
void makedef(void) /* メイク処理のメイン */
{
char *p;
for( ; getline()!=NULL ; line++ )
{
if( strchr(linebuf,'=') )
macset(linebuf); /* 変数定義 */
else
if( linebuf[0]=='.' )
commands(linebuf+1); /* コマンド発行 */
else
if( (p=strchr(linebuf,':'))!=NULL && p!=linebuf &&
( *(p-1)==' ' || *(p-1)=='\t' ) )
premake(linebuf); /* 条件と命令の保存 */
else
{
printf(" %s %d: syntax error.(command not found)\n",mfname,line);
exit(1);
}
}
}
void initstct(void) /* 全ての構造体の根幹を作る */
{
mdefd=(struct def4way *)elloc(sizeof(struct def4way));
defd = mdefd;
defd->sp =NULL;
defd->spn=NULL;
defd->src=NULL;
defd->dst=NULL; /* tree構造の根幹 */
mdefw=(struct defdflt *)elloc(sizeof(struct defdflt));
defw = mdefw;
defw->src="\0";
defw->dst="\0";
defw->spn=NULL;
defw->sp =NULL; /* tree構造の根幹 */
mdefm=(struct defmac *)elloc(sizeof(struct defmac));
defm = mdefm;
defm->sp =NULL;
defm->src="\0";
defm->dst="\0"; /* tree構造の根幹 */
}
void listing(void) /* 依存関係のリストを表示する */
{
for( tdefd=mdefd->sp ; tdefd!=NULL ; tdefd=tdefd->sp ) {
printf("---*---*---*---*---\n");
printf(" target:");
for( tdefa=tdefd->dst ; tdefa!=NULL ; tdefa=tdefa->sp )
printf(" %s",tdefa->cen);
printf("\n source:");
for( tdefb=tdefd->src ; tdefb!=NULL ; tdefb=tdefb->sp )
printf(" %s",tdefb->cen);
printf("\n");
}
printf("---* end of list\n");
}
/*
メイン
*/
int main(int argc,char *argv[]) /* メイン */
{
char *p;
int cm;
initstct(); /* tree構造体の初期化 */
doImake=TRUE;
for( cm=1 ; cm<argc ; cm++ )
{
p=argv[cm];
if( *p!='-' )
{
doImake=FALSE;
break;
}
else
switch(*(p+1))
{
case'?':
case'h':
case'H':
printf(helpmes);
exit(0);
case'c':
doIcomm=TRUE;
break;
case'd':
doIdisp=FALSE;
break;
case'e':
doIexec=FALSE;
break;
case'm':
doIdval=TRUE;
break;
case'p':
doIdpro=TRUE;
break;
case'f':
mfname=argv[++cm];
break;
case'i':
doIlist=TRUE;
break;
case'v':
doIigno=TRUE;
break;
case'D':
defmac(argv[cm]+2,argv[cm+1]);
cm++;
break;
case't':
doIolyt=TRUE;
break;
default:
printf(" illegal option'%c'.\n",*(p+1));
exit(2);
}
}
if( (fp=fopen(mfname,"r"))==NULL )
{
printf(" fatal: '%s' not found.\n",mfname);
return(2);
} /* file open */
makedef(); /* 総合前処理 */
for( ; cm<argc ; cm++ ) {
if( *argv[cm]=='-' ) {
printf(" %s: オプションがファイルの後にある.\n",mfname);
exit(1);
}
setbase();
defa->cen=argv[cm];
if( (defd->spn=searsrc(defd,0))==NULL ) {
printf(" %s: Don't know how to make '%s'.\n",mfname,argv[cm]);
exit(1);
}
}
if( doIlist==TRUE )
listing(); /* 依存関係表示 */
if( doIdval==TRUE ) {
printf("---* macro list\n");
for( mdefm=mdefm->sp ; mdefm!=NULL ; mdefm=mdefm->sp )
printf(" $(%s)='%s'\n",mdefm->src,mdefm->dst);
printf("---* end of list\n");
} /* マクロ表示 */
make(); /* 蓄積したデータを処理する */
if( high==TRUE )
if( highest )
printf(" '%s' is up to date.\n",highest);
else
printf(" No targets.\n");
/* 終了メッセージ表示 */
return 0; /* 正常終了 */
}